package com.sheye.Util;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/** 工具类
 * @author Sheye
 * @date 2019-04-19 21:36
 *
 * getResourceAsStream动态回到当前工程的src目录下
 *
 * 封装了classforname 和 connction两个步骤
 * 还可以封装prepareStatement,不过增删改的时候要设置手动提交，需要conn，只适用于查询
 */
public class JdbcUtil {
    private static String driver;
    private static String url;
    private static String username;
    private static String password;
    //静态块优先级最高
    static {
        //创建properties对象获取属性文件的内容
        Properties p = new Properties();
        //获取属性文件的读取流对象
        InputStream is = JdbcUtil.class.getResourceAsStream("/db.properties");
        try {
            //加载属性配置文件
            p.load(is);
            //获取jdbc参数
            driver=p.getProperty("driver");
            url=p.getProperty("url");
            username=p.getProperty("username");
            password=p.getProperty("password");
            try {
                Class.forName(driver);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
    //封装连接对象
    public static Connection getConnection(){
        Connection conn=null;
        try {
            conn = DriverManager.getConnection(url,username,password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

    //封装sql对象
    public static PreparedStatement getStatement(String sql){
        PreparedStatement ps =null;
        try {
            ps = getConnection().prepareStatement(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return ps;
    }

    //关闭资源
    public static void closeAll(ResultSet rs, Statement stat,Connection conn){
        //PrepareStatement是Statement的子类，根据多态，PrepareStatement也能传
        //没有rs的话。传参直接传null
        try {
            rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            stat.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    //封装DML
    public static int eccuteDML(String sql,Object...objs) throws SQLException {
        //创建连接对象
        Connection conn = getConnection();
        //创建手动确认
        conn.setAutoCommit(false);
        //创建sql对象
        PreparedStatement ps=getStatement(sql);
        //给占位符赋值
        try {
            for (int i=0;i<objs.length;i++){
            ps.setObject(i+1,objs[i]);  //objs可变参数底层是一个数组 所以i+1
            }
            //执行sql命令
            int i =ps.executeUpdate();
            conn.commit();
            return  i;  //是一个整数
        } catch (SQLException e) {
            conn.rollback();
            e.printStackTrace();
        }

        //关闭资源
        closeAll(null,ps,conn);
        return  -1;
    }
}
